"""
智能体API路由

提供智能体管理和任务处理的API接口。
"""

from typing import Dict, List, Any, Optional
from datetime import datetime
from fastapi import APIRouter, HTTPException, Depends, Query, Path
from pydantic import BaseModel, Field

from ..agents.agent_registry import AgentRegistry
from ..agents.agent_roles import AgentRole
from ..dependencies import get_agent_registry


router = APIRouter(prefix="/agents", tags=["agents"])


# 请求模型
class TaskRequest(BaseModel):
    """任务请求模型"""
    task_type: str = Field(..., description="任务类型")
    parameters: Dict[str, Any] = Field(default_factory=dict, description="任务参数")
    priority: int = Field(default=5, ge=1, le=10, description="任务优先级")
    deadline: Optional[datetime] = Field(None, description="任务截止时间")


class AgentCreateRequest(BaseModel):
    """智能体创建请求模型"""
    agent_id: str = Field(..., description="智能体ID")
    role: str = Field(..., description="智能体角色")
    config: Dict[str, Any] = Field(default_factory=dict, description="智能体配置")


class AgentUpdateRequest(BaseModel):
    """智能体更新请求模型"""
    config: Dict[str, Any] = Field(..., description="智能体配置")
    status: Optional[str] = Field(None, description="智能体状态")


# 响应模型
class AgentInfo(BaseModel):
    """智能体信息模型"""
    agent_id: str
    role: str
    status: str
    capabilities: List[str]
    created_at: datetime
    last_active: Optional[datetime] = None
    task_count: int = 0
    success_rate: float = 0.0


class TaskResponse(BaseModel):
    """任务响应模型"""
    task_id: str
    status: str
    result: Dict[str, Any]
    created_at: datetime
    completed_at: Optional[datetime] = None
    error_message: Optional[str] = None


class AgentListResponse(BaseModel):
    """智能体列表响应模型"""
    agents: List[AgentInfo]
    total: int
    page: int
    page_size: int


# API端点
@router.get("/", response_model=AgentListResponse)
async def list_agents(
    role: Optional[str] = Query(None, description="按角色筛选"),
    status: Optional[str] = Query(None, description="按状态筛选"),
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(20, ge=1, le=100, description="每页大小"),
    registry: AgentRegistry = Depends(get_agent_registry)
) -> AgentListResponse:
    """
    获取智能体列表
    
    Args:
        role: 角色筛选
        status: 状态筛选
        page: 页码
        page_size: 每页大小
        registry: 智能体注册表
        
    Returns:
        智能体列表响应
    """
    try:
        # 获取所有智能体
        all_agents = await registry.list_agents()
        
        # 应用筛选
        filtered_agents = all_agents
        if role:
            filtered_agents = [a for a in filtered_agents if a.role.value == role]
        if status:
            filtered_agents = [a for a in filtered_agents if a.status == status]
        
        # 分页
        total = len(filtered_agents)
        start_idx = (page - 1) * page_size
        end_idx = start_idx + page_size
        page_agents = filtered_agents[start_idx:end_idx]
        
        # 构建响应
        agent_infos = []
        for agent in page_agents:
            agent_info = AgentInfo(
                agent_id=agent.agent_id,
                role=agent.role.value,
                status=agent.status,
                capabilities=[cap.value for cap in agent.capabilities],
                created_at=datetime.now(),  # 实际应从agent获取
                task_count=0,  # 实际应从统计获取
                success_rate=0.95  # 实际应从统计获取
            )
            agent_infos.append(agent_info)
        
        return AgentListResponse(
            agents=agent_infos,
            total=total,
            page=page,
            page_size=page_size
        )
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取智能体列表失败: {str(e)}")


@router.get("/{agent_id}", response_model=AgentInfo)
async def get_agent(
    agent_id: str = Path(..., description="智能体ID"),
    registry: AgentRegistry = Depends(get_agent_registry)
) -> AgentInfo:
    """
    获取智能体详情
    
    Args:
        agent_id: 智能体ID
        registry: 智能体注册表
        
    Returns:
        智能体信息
    """
    try:
        agent = await registry.get_agent(agent_id)
        if not agent:
            raise HTTPException(status_code=404, detail=f"智能体 {agent_id} 不存在")
        
        return AgentInfo(
            agent_id=agent.agent_id,
            role=agent.role.value,
            status=agent.status,
            capabilities=[cap.value for cap in agent.capabilities],
            created_at=datetime.now(),  # 实际应从agent获取
            task_count=0,  # 实际应从统计获取
            success_rate=0.95  # 实际应从统计获取
        )
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取智能体详情失败: {str(e)}")


@router.post("/", response_model=AgentInfo)
async def create_agent(
    request: AgentCreateRequest,
    registry: AgentRegistry = Depends(get_agent_registry)
) -> AgentInfo:
    """
    创建智能体
    
    Args:
        request: 创建请求
        registry: 智能体注册表
        
    Returns:
        智能体信息
    """
    try:
        # 验证角色
        try:
            role = AgentRole(request.role)
        except ValueError:
            raise HTTPException(status_code=400, detail=f"无效的智能体角色: {request.role}")
        
        # 检查智能体是否已存在
        existing_agent = await registry.get_agent(request.agent_id)
        if existing_agent:
            raise HTTPException(status_code=409, detail=f"智能体 {request.agent_id} 已存在")
        
        # 创建智能体（这里需要根据角色创建具体的智能体实例）
        # 实际实现中应该有智能体工厂来创建不同类型的智能体
        success = await registry.register_agent(request.agent_id, role)
        if not success:
            raise HTTPException(status_code=500, detail="智能体注册失败")
        
        # 获取创建的智能体
        agent = await registry.get_agent(request.agent_id)
        
        return AgentInfo(
            agent_id=agent.agent_id,
            role=agent.role.value,
            status=agent.status,
            capabilities=[cap.value for cap in agent.capabilities],
            created_at=datetime.now(),
            task_count=0,
            success_rate=0.0
        )
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"创建智能体失败: {str(e)}")


@router.put("/{agent_id}", response_model=AgentInfo)
async def update_agent(
    agent_id: str = Path(..., description="智能体ID"),
    request: AgentUpdateRequest = ...,
    registry: AgentRegistry = Depends(get_agent_registry)
) -> AgentInfo:
    """
    更新智能体
    
    Args:
        agent_id: 智能体ID
        request: 更新请求
        registry: 智能体注册表
        
    Returns:
        智能体信息
    """
    try:
        agent = await registry.get_agent(agent_id)
        if not agent:
            raise HTTPException(status_code=404, detail=f"智能体 {agent_id} 不存在")
        
        # 更新智能体配置和状态
        # 实际实现中应该调用agent的更新方法
        
        return AgentInfo(
            agent_id=agent.agent_id,
            role=agent.role.value,
            status=request.status or agent.status,
            capabilities=[cap.value for cap in agent.capabilities],
            created_at=datetime.now(),
            task_count=0,
            success_rate=0.95
        )
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"更新智能体失败: {str(e)}")


@router.delete("/{agent_id}")
async def delete_agent(
    agent_id: str = Path(..., description="智能体ID"),
    registry: AgentRegistry = Depends(get_agent_registry)
) -> Dict[str, str]:
    """
    删除智能体
    
    Args:
        agent_id: 智能体ID
        registry: 智能体注册表
        
    Returns:
        删除结果
    """
    try:
        agent = await registry.get_agent(agent_id)
        if not agent:
            raise HTTPException(status_code=404, detail=f"智能体 {agent_id} 不存在")
        
        success = await registry.unregister_agent(agent_id)
        if not success:
            raise HTTPException(status_code=500, detail="智能体注销失败")
        
        return {"message": f"智能体 {agent_id} 已删除"}
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"删除智能体失败: {str(e)}")


@router.post("/{agent_id}/tasks", response_model=TaskResponse)
async def assign_task(
    agent_id: str = Path(..., description="智能体ID"),
    request: TaskRequest = ...,
    registry: AgentRegistry = Depends(get_agent_registry)
) -> TaskResponse:
    """
    分配任务给智能体
    
    Args:
        agent_id: 智能体ID
        request: 任务请求
        registry: 智能体注册表
        
    Returns:
        任务响应
    """
    try:
        agent = await registry.get_agent(agent_id)
        if not agent:
            raise HTTPException(status_code=404, detail=f"智能体 {agent_id} 不存在")
        
        # 创建任务
        task = {
            "type": request.task_type,
            "parameters": request.parameters,
            "priority": request.priority,
            "deadline": request.deadline,
            "created_at": datetime.now()
        }
        
        # 分配任务给智能体
        result = await agent.process_task(task)
        
        # 生成任务ID
        task_id = f"TASK_{datetime.now().strftime('%Y%m%d_%H%M%S')}_{agent_id}"
        
        return TaskResponse(
            task_id=task_id,
            status="completed" if result.get("status") == "success" else "failed",
            result=result,
            created_at=datetime.now(),
            completed_at=datetime.now(),
            error_message=result.get("message") if result.get("status") == "error" else None
        )
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"任务分配失败: {str(e)}")


@router.get("/{agent_id}/tasks")
async def get_agent_tasks(
    agent_id: str = Path(..., description="智能体ID"),
    status: Optional[str] = Query(None, description="任务状态筛选"),
    limit: int = Query(10, ge=1, le=100, description="返回数量限制"),
    registry: AgentRegistry = Depends(get_agent_registry)
) -> List[TaskResponse]:
    """
    获取智能体任务历史
    
    Args:
        agent_id: 智能体ID
        status: 状态筛选
        limit: 数量限制
        registry: 智能体注册表
        
    Returns:
        任务列表
    """
    try:
        agent = await registry.get_agent(agent_id)
        if not agent:
            raise HTTPException(status_code=404, detail=f"智能体 {agent_id} 不存在")
        
        # 实际实现中应该从数据库或缓存获取任务历史
        # 这里返回模拟数据
        tasks = []
        for i in range(min(limit, 5)):
            task = TaskResponse(
                task_id=f"TASK_{datetime.now().strftime('%Y%m%d')}_{i:03d}",
                status="completed",
                result={"status": "success", "message": "任务完成"},
                created_at=datetime.now(),
                completed_at=datetime.now()
            )
            tasks.append(task)
        
        return tasks
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取任务历史失败: {str(e)}")


@router.get("/{agent_id}/status")
async def get_agent_status(
    agent_id: str = Path(..., description="智能体ID"),
    registry: AgentRegistry = Depends(get_agent_registry)
) -> Dict[str, Any]:
    """
    获取智能体状态
    
    Args:
        agent_id: 智能体ID
        registry: 智能体注册表
        
    Returns:
        智能体状态信息
    """
    try:
        agent = await registry.get_agent(agent_id)
        if not agent:
            raise HTTPException(status_code=404, detail=f"智能体 {agent_id} 不存在")
        
        return {
            "agent_id": agent.agent_id,
            "status": agent.status,
            "health": "healthy",
            "last_heartbeat": datetime.now(),
            "current_tasks": 0,
            "queue_size": 0,
            "memory_usage": "45MB",
            "cpu_usage": "12%",
            "uptime": "2h 30m"
        }
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取智能体状态失败: {str(e)}")


@router.post("/{agent_id}/start")
async def start_agent(
    agent_id: str = Path(..., description="智能体ID"),
    registry: AgentRegistry = Depends(get_agent_registry)
) -> Dict[str, str]:
    """
    启动智能体
    
    Args:
        agent_id: 智能体ID
        registry: 智能体注册表
        
    Returns:
        操作结果
    """
    try:
        agent = await registry.get_agent(agent_id)
        if not agent:
            raise HTTPException(status_code=404, detail=f"智能体 {agent_id} 不存在")
        
        # 启动智能体
        # 实际实现中应该调用agent的start方法
        
        return {"message": f"智能体 {agent_id} 已启动"}
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"启动智能体失败: {str(e)}")


@router.post("/{agent_id}/stop")
async def stop_agent(
    agent_id: str = Path(..., description="智能体ID"),
    registry: AgentRegistry = Depends(get_agent_registry)
) -> Dict[str, str]:
    """
    停止智能体
    
    Args:
        agent_id: 智能体ID
        registry: 智能体注册表
        
    Returns:
        操作结果
    """
    try:
        agent = await registry.get_agent(agent_id)
        if not agent:
            raise HTTPException(status_code=404, detail=f"智能体 {agent_id} 不存在")
        
        # 停止智能体
        # 实际实现中应该调用agent的stop方法
        
        return {"message": f"智能体 {agent_id} 已停止"}
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"停止智能体失败: {str(e)}")


@router.get("/roles/available")
async def get_available_roles() -> List[Dict[str, str]]:
    """
    获取可用的智能体角色
    
    Returns:
        角色列表
    """
    try:
        roles = []
        for role in AgentRole:
            roles.append({
                "value": role.value,
                "name": role.name,
                "description": f"{role.value}智能体"
            })
        
        return roles
        
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取角色列表失败: {str(e)}")